home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 November / macformat-018.iso / Utility Spectacular / Developer / macgambit-20-compiler-src-p1 / MacGambit Linker Source / glk.c next >
Encoding:
C/C++ Source or Header  |  1994-07-26  |  10.5 KB  |  487 lines  |  [TEXT/KAHL]

  1. #define MAX_NB_OFILES 64
  2.  
  3. int self_refnum;
  4.  
  5.  
  6. void mem_err()
  7. { UseResFile( self_refnum );
  8.   ParamText( "\pMemory full", "\p", "\p", "\p" );
  9.   StopAlert( 128, 0L );
  10.   ExitToShell();
  11. }
  12.  
  13.  
  14. void file_not_found_err( str )
  15. unsigned char *str;
  16. { UseResFile( self_refnum );
  17.   ParamText( "\pFile \"", str, "\p\" not found", "\p" );
  18.   StopAlert( 128, 0L );
  19.   ExitToShell();
  20. }
  21.  
  22.  
  23. void too_many_ofiles_err()
  24. { UseResFile( self_refnum );
  25.   ParamText( "\pToo many object files (limit is 64)", "\p", "\p", "\p" );
  26.   StopAlert( 128, 0L );
  27.   ExitToShell();
  28. }
  29.  
  30.  
  31. void io_err()
  32. { UseResFile( self_refnum );
  33.   ParamText( "\pIO error", "\p", "\p", "\p" );
  34.   StopAlert( 128, 0L );
  35.   ExitToShell();
  36. }
  37.  
  38.  
  39. void link_script_io_err()
  40. { UseResFile( self_refnum );
  41.   ParamText( "\pIO error while reading link script", "\p", "\p", "\p" );
  42.   StopAlert( 128, 0L );
  43.   ExitToShell();
  44. }
  45.  
  46.  
  47. void res_err()
  48. { UseResFile( self_refnum );
  49.   ParamText( "\pResource error", "\p", "\p", "\p" );
  50.   StopAlert( 128, 0L );
  51.   ExitToShell();
  52. }
  53.  
  54.  
  55. void syntax_err()
  56. { UseResFile( self_refnum );
  57.   ParamText( "\pLink script syntax error", "\p", "\p", "\p" );
  58.   StopAlert( 128, 0L );
  59.   ExitToShell();
  60. }
  61.  
  62.  
  63. unsigned char *p_to_p( p1 )
  64. unsigned char *p1;
  65. { int len = *p1++;
  66.   unsigned char *str = (unsigned char *)NewPtr( (long)len+1 );
  67.   unsigned char *p2 = str;
  68.   if (str == NULL) mem_err();
  69.   *p2++ = len;
  70.   while (len>0) { *p2++ = *p1++; len--; }
  71.   return str;
  72. }
  73.  
  74.  
  75. #define FontNum 4
  76. #define FontSize 9
  77. #define FontH 11
  78. #define FontW 6
  79. #define Border 3
  80.  
  81.  
  82. WindowPtr wind;
  83.  
  84.  
  85. void open_wind()
  86. { Rect bounds;
  87.   int width = 40 /*(screenBits.bounds.right-SBarWidth-2*Border-11)/FontW*/;
  88.   int height = (screenBits.bounds.bottom-2*Border-48)/FontH;
  89.  
  90.   bounds.left   = 0;
  91.   bounds.right  = bounds.left + width*FontW + 2*Border;
  92.   bounds.top    = 43;
  93.   bounds.bottom = bounds.top + height*FontH + 2*Border;
  94.  
  95.   wind = NewWindow( NULL, &bounds, "\pMacGambit Linker", TRUE,
  96.                     documentProc, (WindowPtr)-1L, TRUE, 0L );
  97.   if (wind == NULL) mem_err();
  98.  
  99.   SetPort( wind );
  100.   TextFont( FontNum );
  101.   TextSize( FontSize );
  102. }
  103.  
  104.  
  105. void gotoxy( x, y )
  106. int x, y;
  107. { SetPort( wind );
  108.   MoveTo( x*FontW + Border, y*FontH + Border + FontH );
  109. }
  110.  
  111.  
  112. int done;
  113.  
  114. pascal int mydlog( item, dlog )
  115. int item;
  116. DialogPtr dlog;
  117. { done = (item == 2);
  118.   return item;
  119. }
  120.  
  121.  
  122. int current_volume = 0;
  123.  
  124. int open_file( filename, vol, for_output, res_fork, file_type, file_creator )
  125. Str255 filename;
  126. int vol;
  127. int for_output;
  128. int res_fork;
  129. ResType file_type, file_creator;
  130. { ioParam pb;
  131.   fileParam fp;
  132.   int refnum;
  133.   int len = filename[0];
  134.  
  135.   pb.ioNamePtr = filename;
  136.   pb.ioVRefNum = vol;
  137.   pb.ioVersNum = 0;
  138.   pb.ioPermssn = (for_output) ? fsWrPerm : fsRdPerm;
  139.   pb.ioMisc = 0;
  140.  
  141.   if (for_output)
  142.   { asm
  143.     { lea    pb,a0
  144.       _PBCreate
  145.     }
  146.     if ((pb.ioResult != noErr) && (pb.ioResult != dupFNErr)) return -1;
  147.   }
  148.  
  149.   if (res_fork)
  150.     asm
  151.     { lea    pb,a0
  152.       _PBOpenRF
  153.     }
  154.   else
  155.     asm
  156.     { lea    pb,a0
  157.       _PBOpen
  158.     }
  159.   if (pb.ioResult != noErr)
  160.   { if (for_output)
  161.     { asm
  162.       { lea    pb,a0
  163.         _PBDelete
  164.       }
  165.       return -1;
  166.     }
  167.     if ((pb.ioResult == dirNFErr) || (pb.ioResult == fnfErr)) return -2;
  168.     return -1;
  169.   }
  170.   refnum = pb.ioRefNum;
  171.   
  172.   if (for_output)
  173.   asm
  174.   { lea    pb,a0
  175.     _PBSetEOF
  176.   }
  177.  
  178.   if (for_output)
  179.   { fp.ioNamePtr = filename;
  180.     fp.ioVRefNum = vol;
  181.     fp.ioFVersNum = 0;
  182.     fp.ioFDirIndex = 0;
  183.     asm
  184.     { lea    fp,a0
  185.       _PBGetFInfo
  186.       bmi.s  @1
  187.     }
  188.     fp.ioFlFndrInfo.fdType = file_type;
  189.     fp.ioFlFndrInfo.fdCreator = file_creator;
  190.     asm
  191.     { lea    fp,a0
  192.       _PBSetFInfo
  193.       @1
  194.     }
  195.   }
  196.  
  197.   return refnum;
  198. }
  199.  
  200. struct file {
  201.   unsigned char *name;
  202.   int vrefnum;
  203.   };
  204.  
  205. int nb_ofiles = 0;
  206. struct file ofile[MAX_NB_OFILES+1];
  207. struct file library;
  208. struct file link_script;
  209.  
  210. int link_script_refnum = -1;
  211.  
  212. unsigned char *appl_name;
  213. int appl_refnum;
  214. int first_unused_id;
  215.  
  216.  
  217. void link_library()
  218. { Handle h;
  219.  
  220.   /* copy library file to application file and set finder info */
  221.   int refnum_a, refnum_l;
  222.   long len, count;
  223.   char *mem;
  224.  
  225.   len = library.name[0];
  226.   if ((len >= 5) &&
  227.       (library.name[len-4] == '.') && (library.name[len-3] == 'r') &&
  228.       (library.name[len-2] == 's') && (library.name[len-1] == 'r') &&
  229.       (library.name[len] == 'c'))
  230.     refnum_a = open_file( appl_name, current_volume, 1, 1, 'gamL', 'gamL' );
  231.   else
  232.     refnum_a = open_file( appl_name, current_volume, 1, 1, 'APPL', '????' );
  233.   if (refnum_a <= -1) io_err();
  234.   refnum_l = open_file( library.name, library.vrefnum, 0, 1, '????', '????' );
  235.   if (refnum_l == -2) { FSClose( refnum_a ); file_not_found_err( library.name ); }
  236.   if (refnum_l <= -1) { FSClose( refnum_a ); io_err(); }
  237.  
  238.   if (GetEOF( refnum_l, &len ) != noErr)
  239.   { FSClose( refnum_a ); FSClose( refnum_l ); io_err(); }
  240.  
  241.   mem = NewPtr( len );
  242.   if (mem == NULL)
  243.   { FSClose( refnum_a ); FSClose( refnum_l ); mem_err(); }
  244.  
  245.   count = len;
  246.   if ((FSRead( refnum_l, &count, mem ) != noErr) || (count != len))
  247.   { FSClose( refnum_a ); FSClose( refnum_l ); io_err(); }
  248.  
  249.   if ((FSWrite( refnum_a, &count, mem ) != noErr) || (count != len))
  250.   { FSClose( refnum_a ); FSClose( refnum_l ); io_err(); }
  251.  
  252.   DisposPtr( mem );
  253.  
  254.   FSClose( refnum_a );
  255.   FSClose( refnum_l );
  256.  
  257.   /* open application file's resource fork */
  258.   gotoxy( 0, 0 ); DrawChar( '-' );
  259.  
  260.   appl_refnum = OpenRFPerm( appl_name, current_volume, 0 );
  261.   if (ResError() != noErr) res_err();
  262.   UseResFile( appl_refnum );
  263.   first_unused_id = 127;
  264.   do
  265.   { first_unused_id++;
  266.     SetResLoad( FALSE );
  267.     h = GetResource( 'gamO', first_unused_id );
  268.     SetResLoad( TRUE );
  269.   } while (h != NULL);
  270.   UseResFile( self_refnum );
  271.  
  272.   if ((first_unused_id - 127) + nb_ofiles > MAX_NB_OFILES)
  273.     too_many_ofiles_err();
  274.  
  275.   gotoxy( 0, 0 ); DrawChar( 0xa5 );
  276. }
  277.  
  278.  
  279. void link_ofiles()
  280. { int i;
  281.   for (i=0; i<nb_ofiles; i++)
  282.   { Handle h;
  283.     int refnum;
  284.     long len, count;
  285.     gotoxy( 0, i+1 ); DrawChar( '-' );
  286.  
  287.     refnum = open_file( ofile[i].name, ofile[i].vrefnum, 0, 0, '????', '????' );
  288.     if (refnum == -2) file_not_found_err( ofile[i].name );
  289.     if (refnum <= -1) io_err();
  290.  
  291.     if (GetEOF( refnum, &len ) != noErr)
  292.     { FSClose( refnum ); io_err(); }
  293.  
  294.     h = NewHandle( len );
  295.     if (h == NULL)
  296.     { FSClose( refnum ); mem_err(); }
  297.  
  298.     count = len;
  299.     if ((FSRead( refnum, &count, *h ) != noErr) || (count != len))
  300.     { FSClose( refnum ); io_err(); }
  301.  
  302.     FSClose( refnum );
  303.  
  304.     UseResFile( appl_refnum );
  305.     AddResource( h, 'gamO', first_unused_id+i, 0L );
  306.     if (ResError() != noErr) res_err();
  307.     WriteResource( h );
  308.     if (ResError() != noErr) res_err();
  309.     ReleaseResource( h );
  310.     UseResFile( self_refnum );
  311.  
  312.     gotoxy( 0, i+1 ); DrawChar( 0xa5 );
  313.   }
  314. }
  315.  
  316.  
  317. void link_end()
  318. { CloseResFile( appl_refnum );
  319.   if (ResError() != noErr) res_err();
  320.   RsrcZoneInit();
  321.   ExitToShell();
  322. }
  323.  
  324.  
  325. int read_link_script_line( f )
  326. struct file *f;
  327. {
  328.   Str255 name;
  329.   int n = 0, err;
  330.   long count;
  331.   char c;
  332.   while (1)
  333.   {
  334.     count = 1;
  335.     err = FSRead( link_script_refnum, &count, &c );
  336.     if (err != noErr)
  337.     { FSClose( link_script_refnum );
  338.       if (err == eofErr) break; else link_script_io_err();
  339.     }
  340.     if (c == '\r') break;
  341.     n++;
  342.     name[n] = c;
  343.   }
  344.   name[0] = n;
  345.   f->name = p_to_p( name );
  346.   f->vrefnum = current_volume;
  347.   return (err == eofErr);
  348. }
  349.  
  350.  
  351. int main( argc, argv )
  352. int argc;
  353. char *argv[];
  354. { int i, eof;
  355.  
  356.   InitGraf( &thePort );
  357.   InitFonts();
  358.   FlushEvents( everyEvent, 0 );
  359.   InitWindows();
  360.   InitMenus();
  361.   TEInit();
  362.   InitDialogs( 0L );
  363.   InitCursor();
  364.  
  365.   self_refnum = CurResFile();
  366.  
  367.   open_wind();
  368.  
  369.   i = 0;
  370.   { int msg, count;
  371.     CountAppFiles( &msg, &count );
  372.     if (msg == appOpen)
  373.     { for (i=1; i<=count; i++)
  374.       { AppFile file_info;
  375.         GetAppFiles( i, &file_info );
  376.         if (file_info.fType == 'TEXT')
  377.         { ClrAppFiles( i );
  378.           link_script.name    = p_to_p( file_info.fName );
  379.           link_script.vrefnum = file_info.vRefNum;
  380.           current_volume      = file_info.vRefNum;
  381.           goto found_link_script;
  382.         }
  383.         else if (file_info.fType == 'gamL')
  384.         { ClrAppFiles( i );
  385.           library.name    = p_to_p( file_info.fName );
  386.           library.vrefnum = file_info.vRefNum;
  387.           current_volume  = file_info.vRefNum;
  388.           goto found_lib;
  389.         }
  390.       }
  391.       i = 0;
  392.     }
  393.   }
  394.  
  395.   { SFTypeList type;
  396.     Point where = { 70, 155 };
  397.     SFReply reply;
  398.     type[0] = 'TEXT';
  399.     type[1] = 'gamL';
  400.     SFPGetFile( where, "\pSelect link script or library to link", 0L, 2, type, &mydlog, &reply, 128, 0L );
  401.     if (!reply.good) return 0;
  402.     if (reply.fType == 'TEXT')
  403.     { link_script.name    = p_to_p( reply.fName );
  404.       link_script.vrefnum = reply.vRefNum;
  405.       goto found_link_script;
  406.     }
  407.     else
  408.     { library.name    = p_to_p( reply.fName );
  409.       library.vrefnum = reply.vRefNum;
  410.       goto found_lib;
  411.     }
  412.   }
  413.  
  414.   found_link_script:
  415.  
  416.   link_script_refnum = open_file( link_script.name, link_script.vrefnum, 0, 0, '????', '????' );
  417.   if (link_script_refnum <= -1) io_err();
  418.  
  419.   if (read_link_script_line( &library )) syntax_err();
  420.  
  421.   found_lib:
  422.  
  423.   gotoxy( 1, 0 );
  424.   DrawString( library.name );
  425.   DrawString( "\p (Library)" );
  426.  
  427.   do
  428.   {
  429.     if (link_script_refnum != -1)
  430.     { eof = read_link_script_line( &ofile[nb_ofiles] );
  431.       done = (ofile[nb_ofiles].name[0] == 0);
  432.       if (!done)
  433.       { nb_ofiles++;
  434.         gotoxy( 1, nb_ofiles );
  435.         DrawString( ofile[nb_ofiles-1].name );
  436.       }
  437.       else
  438.         if (nb_ofiles == 0) syntax_err();
  439.     }
  440.     else
  441.     { SFTypeList type;
  442.       Point where = { 70, 155 };
  443.       SFReply reply;
  444.       type[0] = 'gamO';
  445.       SFPGetFile( where, "\pSelect object file to link", 0L, 1, type, &mydlog, &reply, ((nb_ofiles)?129:128), 0L );
  446.       if (!done)
  447.       { if (!reply.good) return 0;
  448.         ofile[nb_ofiles].name    = p_to_p( reply.fName );
  449.         ofile[nb_ofiles].vrefnum = reply.vRefNum;
  450.         nb_ofiles++;
  451.         gotoxy( 1, nb_ofiles );
  452.         DrawString( ofile[nb_ofiles-1].name );
  453.       }
  454.     }
  455.   } while ((!done) && (nb_ofiles <= MAX_NB_OFILES));
  456.  
  457.   if (nb_ofiles > MAX_NB_OFILES) too_many_ofiles_err();
  458.  
  459.   if ((link_script_refnum != -1) && !eof)
  460.   { struct file f;
  461.     if (read_link_script_line( &f )) syntax_err();
  462.     appl_name = f.name;
  463.     if (appl_name[0] == 0) syntax_err();
  464.   }
  465.   else
  466.   { int len;
  467.     appl_name = p_to_p( ofile[nb_ofiles-1].name );
  468.     len = appl_name[0];
  469.     if ((len >= 2) &&
  470.         (appl_name[len-1] == '.') && (appl_name[len] == 'O'))
  471.     { int i = 1, j = len;
  472.       while ((j > 0) && (appl_name[j] != ':')) j--;
  473.       appl_name[0] = (len-2)-j;
  474.       j++;
  475.       while (j <= len) appl_name[i++] = appl_name[j++];
  476.     }
  477.     else
  478.       appl_name = "\pApplication";
  479.   }
  480.  
  481.   link_library();
  482.  
  483.   link_ofiles();
  484.  
  485.   link_end();
  486. }
  487.